package movEat.GUI;

import java.util.ArrayList;
import java.util.List;

import movEat.Definitions.Genre;
import movEat.Definitions.MovieDB;
import movEat.Definitions.Rating;
import movEat.Kernel.Import.Utils;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class MovieParametersComposite {

	private Composite Composite;
	private Text movieName;
	private Text movieStars;
	private Text movieCountry;
	private Button movieIsDrink_Yes;
	private Button movieIsDrink_No;
	private Button movieIsDrink_DontKnow;
	private Combo movieRating;
	private ArrayList<Button> genresList;
	private Text movieYear;

	public MovieParametersComposite(Composite father,
			boolean isDrink_enableDontKnow, boolean showLabels) {
		Composite = new Composite(father, SWT.NONE);
		Composite.setLayout(new GridLayout(1, false));
		Composite.setLayoutData(new GridData(SWT.NONE, SWT.NONE, false, false,
				SWT.FILL, SWT.NONE));

		Composite editMovies_Params = new Composite(Composite, SWT.NONE);
		editMovies_Params.setLayout(new RowLayout());
		editMovies_Params.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false,
				false, SWT.NONE, SWT.NONE));
		if (showLabels) {
			Label movieNameLabel = new Label(editMovies_Params, SWT.NONE);
			movieNameLabel.setText("The movie's name: ");
			movieNameLabel.setFont(new Font(SWTUtil.getDisplay(),
					"Segoe Print", 8, SWT.NONE));
		}
		movieName = new Text(editMovies_Params, SWT.BORDER);
		movieName
				.setText("The movie's name                                       ");
		movieName.setFont(new Font(SWTUtil.getDisplay(), "Segoe Print", 8,
				SWT.NONE));
		movieName.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				if (movieName
						.getText()
						.equals("The movie's name                                       "))
					movieName.setText("");
			}

			@Override
			public void focusLost(FocusEvent e) {
				if (movieName.getText().equals(""))
					movieName
							.setText("The movie's name                                       ");
			}
		});

		if (showLabels) {
			Label moviePriceLabel = new Label(editMovies_Params, SWT.NONE);
			moviePriceLabel.setText("The movie's price: ");
			moviePriceLabel.setFont(new Font(SWTUtil.getDisplay(),
					"Segoe Print", 8, SWT.NONE));
		}
		movieStars = new Text(editMovies_Params, SWT.BORDER);
		movieStars.setText("The movie's price (0-100 $)");
		movieStars.setFont(new Font(SWTUtil.getDisplay(), "Segoe Print", 8,
				SWT.NONE));
		movieStars.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				e.doit = false; // don't allow anything but numbers and
								// backspace
				if (Character.isDigit(e.character) || e.keyCode == SWT.BS
						|| e.keyCode == SWT.DEL) {
					e.doit = true;
				}
			}
		});

		movieStars.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				if (movieStars.getText().equals("The movie's price (0-100 $)"))
					movieStars.setText("");
			}

			@Override
			public void focusLost(FocusEvent e) {
				if (movieStars.getText().equals(""))
					movieStars.setText("The movie's price (0-100 $)");
			}
		});

		if (showLabels) {
			Label movieCountryLabel = new Label(editMovies_Params, SWT.NONE);
			movieCountryLabel.setText("The movie's origin: ");
			movieCountryLabel.setFont(new Font(SWTUtil.getDisplay(),
					"Segoe Print", 8, SWT.NONE));
		}
		movieCountry = new Text(editMovies_Params, SWT.BORDER);
		movieCountry.setText("From which country");
		movieCountry.setFont(new Font(SWTUtil.getDisplay(), "Segoe Print", 8,
				SWT.NONE));

		movieCountry.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				if (movieCountry.getText().equals("From which country"))
					movieCountry.setText("");
			}

			@Override
			public void focusLost(FocusEvent e) {
				if (movieCountry.getText().equals(""))
					movieCountry.setText("From which country");
			}
		});

		if (showLabels) {
			Label movieYearLabel = new Label(editMovies_Params, SWT.NONE);
			movieYearLabel.setText("The movie's year: ");
			movieYearLabel.setFont(new Font(SWTUtil.getDisplay(),
					"Segoe Print", 8, SWT.NONE));
		}
		movieYear = new Text(editMovies_Params, SWT.BORDER);
		movieYear.setText("When was it made");
		movieYear.setFont(new Font(SWTUtil.getDisplay(), "Segoe Print", 8,
				SWT.NONE));
		movieYear.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				e.doit = false; // don't allow anything but numbers and
								// backspace
				if (Character.isDigit(e.character) || e.keyCode == SWT.BS
						|| e.keyCode == SWT.DEL) {
					e.doit = true;
				}
			}
		});

		movieYear.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				if (movieYear.getText().equals("When was it made"))
					movieYear.setText("");
			}

			@Override
			public void focusLost(FocusEvent e) {
				if (movieYear.getText().equals(""))
					movieYear.setText("When was it made");
			}
		});

		if (showLabels) {
			Label drinkLabel = new Label(Composite, SWT.NONE);
			drinkLabel
					.setText("is it a drink? if so, also select a Rating from the list below.");
			drinkLabel.setFont(new Font(SWTUtil.getDisplay(), "Segoe Print", 8,
					SWT.BOLD));
		}
		Composite isDrinkComposite = new Composite(Composite, SWT.NONE
				| SWT.NONE);
		isDrinkComposite.setLayout(new GridLayout(2, false));

		Composite isDrinkRadoisComposite = new Composite(isDrinkComposite,
				SWT.NONE);
		FillLayout isDrinkRadiosCompositeLayout = new FillLayout(SWT.VERTICAL);
		isDrinkRadoisComposite.setLayout(isDrinkRadiosCompositeLayout);

		movieIsDrink_Yes = new Button(isDrinkRadoisComposite, SWT.RADIO);
		movieIsDrink_Yes.setText("Yes");
		movieIsDrink_Yes.setFont(new Font(SWTUtil.getDisplay(), "Segoe Print",
				8, SWT.NONE));

		movieIsDrink_Yes.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (movieIsDrink_Yes.getSelection())
					movieRating.setEnabled(true);
				else
					movieRating.setEnabled(false);

			}
		});

		movieIsDrink_No = new Button(isDrinkRadoisComposite, SWT.RADIO);
		movieIsDrink_No.setText("No");
		movieIsDrink_No.setFont(new Font(SWTUtil.getDisplay(), "Segoe Print",
				8, SWT.NONE));

		if (isDrink_enableDontKnow) {
			movieIsDrink_DontKnow = new Button(isDrinkRadoisComposite,
					SWT.RADIO);
			movieIsDrink_DontKnow.setText("Don't know");
			movieIsDrink_DontKnow.setFont(new Font(SWTUtil.getDisplay(),
					"Segoe Print", 8, SWT.NONE));
			movieIsDrink_DontKnow.setSelection(true);
		}

		movieRating = new Combo(isDrinkComposite, SWT.DROP_DOWN);
		movieRating.add("KIDS");
		movieRating.add("TEENS");
		movieRating.add("ADULTS");
		movieRating.setText("Rating of the movie");
		movieRating.setFont(new Font(SWTUtil.getDisplay(), "Segoe Print", 8,
				SWT.NONE));
		movieRating.setEnabled(false);
		movieRating.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				e.doit = false; // don't allow anything but numbers and
								// backspace

			}
		});

		Label GenreParam = new Label(Composite, SWT.NONE);
		GenreParam.setText("Genres of the movie");
		GenreParam.setFont(new Font(SWTUtil.getDisplay(), "Segoe Print", 8,
				SWT.BOLD));

		Composite genres = new Composite(Composite, SWT.NONE);
		genres.setLayout(new GridLayout(7, false));
		genresList = new ArrayList<Button>();
		for (Genre genre : Genre.values()) {
			Button newGenreButton = new Button(genres, SWT.CHECK);
			newGenreButton.setText(genre.toString());
			newGenreButton.setFont(new Font(SWTUtil.getDisplay(),
					"Segoe Print", 8, SWT.NONE));

			genresList.add(newGenreButton);
		}

	}

	public void setEnabled(boolean b) {
		Composite.setEnabled(b);

	}

	public void setName(String imdbName) {
		movieName.setText(imdbName);
	}

	public void setStars(String stars) {
		movieStars.setText(stars);

	}

	public void setCountry(String country) {
		movieCountry.setText(country);

	}

	public void setYear(String year) {
		movieYear.setText(year);

	}

	public void setIsDrink_yes(boolean b) {
		movieIsDrink_Yes.setSelection(b);

	}

	public void setRating(String rating) {
		movieRating.setText(rating);

	}

	public void setRatingEnable(boolean b) {
		movieRating.setEnabled(b);

	}

	public void setIsDrink_no(boolean b) {
		movieIsDrink_No.setSelection(b);

	}

	private ArrayList<Button> getGenresButtons() {
		return genresList;
	}

	private String getName() {
		return movieName.getText();
	}

	private String getStars() {
		return movieStars.getText();
	}

	private String getCountry() {
		return movieCountry.getText();
	}

	private String getYear() {
		return movieYear.getText();
	}

	private boolean getIsDrink_yes_Selection() {
		return movieIsDrink_Yes.getSelection();
	}

	private String getRating() {
		return movieRating.getText();
	}

	private boolean getIsDrink_no_selection() {
		return movieIsDrink_No.getSelection();
	}

	public MovieDB getMovieDBFromUserInput_find() {
		String error = verifyUserInput_findMovies();

		if (!error.equals("")) {
			GUI.userMessage(GUI.shell, "Not A vald Input", error);
			return null;
		}

		MovieDB movie = new MovieDB();

		movie.setImdbName(getName());

		String stars = getStars();
		if (stars.equals("") || stars.equals("The movie's price (0-100 $)"))
			movie.setStars(-1);
		else
			movie.setStars(Double.valueOf(stars));

		String country = getCountry();
		if (country.equals("From which country") || country.equals(""))
			movie.setCountry(null);
		else
			movie.setCountry(country);

		String year = getYear();
		if (year.equals("") || year.equals("When was it made"))
			movie.setYear(-1);
		else
			movie.setYear(Integer.valueOf(year));

		if (getIsDrink_yes_Selection()) {
			movie.setIsDrink(true);
			String rating = getRating();
			movie.setRating(Rating.valueOf(rating));
		} else if (getIsDrink_no_selection()) {
			movie.setIsDrink(false);
			movie.setRating(null);
		} else {
			movie.setIsDrink(null);
			movie.setRating(null);
		}

		List<Genre> genres = getGenresFromCheckBoxList(getGenresButtons());

		if (genres.size() == 0)
			movie.setGenres(null);
		else
			movie.setGenres(genres);
		return movie;

	}

	private String verifyUserInput_findMovies() {
		String error = "";

		if (getName().equals("")
				|| getName()
						.equals("The movie's name                                       "))
			error += "please type a movie name or a part of it.\n";

		if (getName().indexOf('_') != -1 || getName().indexOf('%') != -1)
			error += "The name can not contain the chars '%' and '_'";

		if (!Utils.isValidAscii(getName()))
			error += "please write the name in Ascii (english for example).\n";
		
		if (!Utils.isValidAscii(getCountry()))
			error += "please write the name in Ascii (english for example).\n";
		
		if (!getStars().equals("The movie's price (0-100 $)")
				&& !getStars().equals("")) {
			double stars = Double.valueOf(getStars());
			if (stars < 0 || stars > 100)
				error += "The price must be in the range 0-100.\n";
		}

		if (getIsDrink_yes_Selection()) {
			String rating = getRating();
			if (!rating.equals("KIDS") && !rating.equals("TEENS")
					&& !rating.equals("ADULTS"))
				error += "rating must be one of the members in the list of ratings.\n";

		}

		return error;
	}

	private List<Genre> getGenresFromCheckBoxList(ArrayList<Button> genresList) {
		ArrayList<Genre> genres = new ArrayList<Genre>();

		for (Button button : genresList) {
			if (button.getSelection())
				genres.add(Genre.valueOf(button.getText()));
		}

		return genres;
	}

	public MovieDB getMovieDBFromUserInput_edit() {

		String error = verifyUserInput_editMovies();

		if (!error.equals("")) {
			if (GUI.subShell != null && !GUI.subShell.isDisposed())
				GUI.userMessage(GUI.subShell, "Not A vald Input", error);
			else
				GUI.userMessage(GUI.shell, "Not A vald Input", error);
			
			return null;
		}

		MovieDB movie = new MovieDB();

		movie.setImdbName(getName());

		String stars = getStars();
		movie.setStars(Double.valueOf(stars));

		String country = getCountry();
		movie.setCountry(country);

		String year = getYear();
		movie.setYear(Integer.valueOf(year));

		if (getIsDrink_yes_Selection()) {
			movie.setIsDrink(true);
			String rating = getRating();
			movie.setRating(Rating.valueOf(rating));
		} else {
			movie.setIsDrink(false);
			movie.setRating(null);
		}

		List<Genre> genres = getGenresFromCheckBoxList(getGenresButtons());
		movie.setGenres(genres);
		return movie;

	}

	private String verifyUserInput_editMovies() {
		String error = "";

		if (getName().equals("") || getName().equals("The movie's name                                       "))
			error += "please type a Name for the movie.\n";

		// if(getName().indexOf('_')!=-1 || getName().indexOf('%')!=-1)
		// error += "The name can not contain the chars '%' and '_'";

		if (!Utils.isValidAscii(getName()))
			error += "please write the name in Ascii (english for example).\n";
		
		if (getStars().equals(""))
			error += "Please select a price (0-100 $) for the movie.\n";

		else {
			double stars = Double.valueOf(getStars());
			if (stars < 0 || stars > 100)
				error += "The Price be in the range 0-100 $.\n";
		}

		if (getCountry().equals(""))
			error += "please type a Country for the movie.\n";

		if (!Utils.isValidAscii(getCountry()))
			error += "please write the country in Ascii (english for example).\n";
		
		if (getYear().equals(""))
			error += "please type a Year for the movie.\n";

		if (getIsDrink_yes_Selection()) {
			String rating = getRating();
			if (rating.equals("") || rating.equals("The movie Rating"))
				error += "rating must be one of the members in the list of ratings.\n";

		}

		List<Genre> genres = getGenresFromCheckBoxList(getGenresButtons());
		if (genres.size() == 0) {
			error += "Please select at least one Genre for the movie.\n";
		}

		return error;
	}

	public void putMovie(MovieDB selectedMovie) {
		if (selectedMovie != null) {

			if (selectedMovie.getImdbName() != null)
				setName(selectedMovie.getImdbName());
			else
				setName("THERE IS NO NAME FOR THIS MOVIE");

			setStars("" + selectedMovie.getStars());

			if (selectedMovie.getCountry() != null)
				setCountry(selectedMovie.getCountry());
			else
				setCountry("THERE IS NO COUNTRY FOR THIS MOVIE");

			setYear("" + selectedMovie.getYear());

			if (selectedMovie.getIsDrink() != null) {
				if (selectedMovie.getIsDrink()) {
					setIsDrink_yes(true);
					if (selectedMovie.getRating() != null) {
						String rating = getRating(selectedMovie.getRating()
								.toString());
						setRating(rating);
						setRatingEnable(true);
					} else
						setRating("THERE IS NO RATING FOR THIS MOVIE");

				} else {
					setIsDrink_no(true);
					setRatingEnable(false);
				}
			}

			List<Genre> genresOfSelectedMovie = selectedMovie.getGenres();
			if (genresOfSelectedMovie != null) {
				for (Button genreButton : getGenresButtons()) {
					try {
						Genre ButtonGenre = Genre
								.valueOf(genreButton.getText());
						if (genresOfSelectedMovie.contains(ButtonGenre))
							genreButton.setSelection(true);
					} catch (Exception e) {
						if (GUI.subShell != null)
							GUI.userMessage(GUI.subShell, "Error",
									"sorry,\nBut there was an Error firguring out the movie's genres.");
						else
							GUI.userMessage(GUI.shell, "Error",
									"sorry,\nBut there was an Error firguring out the movie's genres.");

					}
				}

			}

		}

	}

	private String getRating(String string) {
		if (string.equals("beer"))
			return "ADULTS";
		else if (string.equals("soft drink"))
			return "KIDS";
		else
			return "TEENS";
	}

	public MovieDB getMovieDBFromUserInput_add() {

		String error = varifyUserInput_addMovies();

		if (!error.equals("")) {
			GUI.userMessage(GUI.shell, "Not A vald Input", error);
			return null;
		}

		MovieDB movie = new MovieDB();

		movie.setImdbName(getName());

		String stars = getStars();
		movie.setStars(Double.valueOf(stars));

		String country = getCountry();
		movie.setCountry(country);

		String year = getYear();
		movie.setYear(Integer.valueOf(year));

		if (getIsDrink_yes_Selection()) {
			movie.setIsDrink(true);
			String rating = getRating();
			movie.setRating(Rating.valueOf(rating));
		} else {
			movie.setIsDrink(false);
			movie.setRating(null);
		}

		List<Genre> genres = getGenresFromCheckBoxList(getGenresButtons());
		movie.setGenres(genres);
		return movie;
	}

	private String varifyUserInput_addMovies() {
		String error = "";

		if (getName().equals("") || getName().equals("The movie's name                                       "))
			error += "please type a Name for the movie.\n";

		// if(getName().indexOf('_')!=-1 || getName().indexOf('%')!=-1)
		// error += "The name can not contain the chars '%' and '_'";

		if (!Utils.isValidAscii(getName()))
			error += "please write the name in Ascii (english for example).\n";
		
		if (getStars().equals("")
				|| getStars().equals("The movie's price (0-100 $)"))
			error += "Please select a price (0-100 $) for the movie.\n";

		else {
			double stars = Double.valueOf(getStars());
			if (stars < 0 || stars > 100)
				error += "The Price must be in the range 0-100 $.\n";
		}

		if (getCountry().equals("")
				|| getCountry().equals("From which country"))
			error += "please type a Country for the movie.\n";

		if (!Utils.isValidAscii(getCountry()))
			error += "please write the country in Ascii (english for example).\n";
		
		if (getYear().equals("") || getYear().equals("When was it made"))
			error += "please type a Year for the movie.\n";
		else {
			double year = Double.valueOf(getYear());
			if (year < 0 || year > 2012)
				error += "The year must be in the range 1895-2012.\n";
		}

		if (getIsDrink_yes_Selection()) {
			String rating = getRating();
			if (rating.equals("") || rating.equals("The movie Rating"))
				error += "rating must be one of the members in the list of ratings.\n";
		}

		List<Genre> genres = getGenresFromCheckBoxList(getGenresButtons());
		if (genres.size() == 0) {
			error += "Please select at least one Genre for the movie.\n";
		}

		return error;
	}

}
